import { Dropbox, DropboxAuth, files } from "dropbox";
import { CacheUtils } from "../cache";
import { ACCESS_TOKEN_CAHCHE_KEY, AUTH_DIRECT_URL, BACKUP_NAME } from "./conf";

export class DropboxUtils implements BackupDriver {
    getTokenWithCode(_code: string, _hash: string): Promise<string | undefined | null> {
        throw new Error("Method not implemented.");
    }
    async getToken(hash: string) {
        const params = new URLSearchParams(hash)
        return params.get('access_token')
    }
    async getCode(hash: string) {
        const params = new URLSearchParams(hash)
        return params.get('code')
    }
    getTokenExpires(hash: string) {
        const params = new URLSearchParams(hash)
        return params.get('expires_in')
    }
    public authUtils = new DropboxAuth({
        clientId: 'txi5og1owpaocma',
    })

    public CACHE_KEY = 'dropbox-'

    public name = 'Dropbox'

    public getCacheKey() {
        return this.CACHE_KEY + ACCESS_TOKEN_CAHCHE_KEY
    }
    public async isAuth() {
        const accessToken = await CacheUtils.get(this.getCacheKey())
        return !!accessToken
    }

    public async init() {

    }
    public async auth(): Promise<string> {
        const res = await this.authUtils.getAuthenticationUrl(AUTH_DIRECT_URL, 'code', 'token', 'legacy')
        return res.toString()
    }

    public async cancelAuth() {
        await CacheUtils.remove(this.getCacheKey())
    }

    public async load(): Promise<BackupFile | undefined> {
        const accessToken = await CacheUtils.get(this.getCacheKey())
        const dbx = new Dropbox({ accessToken })
        const res = await dbx.filesListFolder({ path: '' })
        const meta = res.result.entries.find(item => item.name === BACKUP_NAME)
        if (!meta) {
            return
        }
        const data = meta as files.FileMetadataReference
        const file = await dbx.filesDownload({ path: data.id })

        return {
            file: (file.result as any).fileBlob,
            id: data.id
        }
    }

    public async save(file: Blob) {
        const info = await this.load()
        if (info) {
            await this.delete()
        }
        const accessToken = await CacheUtils.get(this.getCacheKey())
        const dbx = new Dropbox({ accessToken })
        await dbx.filesUpload({
            path: '/' + BACKUP_NAME,
            contents: file
        })
    }

    public async delete() {
        const accessToken = await CacheUtils.get(this.getCacheKey())
        const dbx = new Dropbox({ accessToken })
        await dbx.filesDeleteV2({
            path: '/' + BACKUP_NAME
        })
    }

}